package com.gxatek.cockpit.dvr.service.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.List;

/**
 * 0.001到0.999共1000个值，相当于1000个点，屏幕高度就1000，上半部分显示小于平均值1的，下半部分显示大于平均值1的数据
 */

public class CustomLineChart extends View {
    String TAG = "CustomLineChart";
    //设置刻度最大最小值，在中间值，上下个单位的，比如重力加速度是9.79的样子，最大就是10.79，最小就选择8.79，中间的就是平均值9.78
    private float maxValue = 0;
    private float minValue = 0;
    String desc;
    private List<Float> data;
    private Paint linePaint;
    private Paint pointPaint;
    private Paint clickLinePaint;
    private Paint descPaint;
    private int descPaintColor = Color.BLUE;

    float deltaX;//很坐标两个点之间的距离是多少，如果数据逐渐增加，这个值会一直变化，达到最大的数量是，这个值就不会变了

    public PointClickListener onPointClickListener;

    public int showIndex = -1; //画竖线的地方

    public void setOnPointClickListener(PointClickListener onPointClickListener) {
        this.onPointClickListener = onPointClickListener;
    }

    //这里提供一个手动设置的方法，都传入第一个数据的值，如果这个值的在正负1直接，那就手动设置max为2，min为-2，固定这个纵轴最大和最小值，同时会根据传入的data集合修改这两个值的大小（这个值）
    //最大和最小值在平均值(给的值加2或者减2的方位内容，这样波形图就比较稳定)
    public void setMaxValue(float maxValue) {
        float temp = Math.round(maxValue) + 0.5f;
        if (temp > maxValue) {
            this.maxValue = temp;
        }
    }

    public void setMinValue(float minValue) {
        float temp = Math.round(minValue) - 0.5f;
        if(temp < minValue ){
            this.minValue = temp;
        }
    }
    public void setDescPaintColor(int color){
        this.descPaintColor = color;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }

    public CustomLineChart(Context context) {
        super(context);
        init();
    }

    public CustomLineChart(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        linePaint = new Paint();
        linePaint.setColor(Color.BLUE);
        linePaint.setStrokeWidth(2f);
        linePaint.setStyle(Paint.Style.STROKE);

        clickLinePaint = new Paint();
        clickLinePaint.setColor(Color.BLUE);
        clickLinePaint.setStrokeWidth(1f);
        clickLinePaint.setStyle(Paint.Style.STROKE);

        pointPaint = new Paint();
        pointPaint.setColor(Color.RED);
        pointPaint.setStyle(Paint.Style.FILL);
        pointPaint.setStrokeWidth(0);

        descPaint = new Paint();
        descPaint.setColor(Color.GRAY);
        descPaint.setStyle(Paint.Style.FILL);
        descPaint.setStrokeWidth(14);

        data = new ArrayList<>();
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    public void setData(List<Float> data) {
        this.data = data;
        if (data != null && !data.isEmpty()) {
            for (int i = 0; i < data.size(); i++) {
                if (Math.round(data.get(i)) < minValue) {
                    minValue = Math.round(data.get(i))-0.5f;
                }
                if (Math.round(data.get(i)) > maxValue) {
                    maxValue = Math.round(data.get(i))+0.5f;
                }
            }
            //minValue = data.stream().min(Float::compareTo).orElse(minValue);
            //maxValue = data.stream().max(Float::compareTo).orElse(maxValue);
        }
        //Log.e(TAG, "maxValue="+maxValue+" minValue="+minValue);
        invalidate(); // 触发重绘
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 检查动作是否为按下
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // 在这里添加点击事件的代码
            int x = (int) event.getX();
            int index = (int) (x / deltaX);
            showIndex = x;
            if (onPointClickListener != null && data.size()>0 && data.size() <index ) { //防止越界
                onPointClickListener.onClick(index);
            }
            invalidate();
            return super.onTouchEvent(event); // 表示事件已处理
        }
        return super.onTouchEvent(event); // 调用父类的onTouchEvent方法处理其他触摸事件
    }

    public static interface PointClickListener {
        void onClick(int index);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (data == null || data.isEmpty()) return;

        int width = getWidth();
        int height = getHeight();

        deltaX = (float) width / (data.size() - 1);
        float deltaYRange = height / (maxValue - minValue);

        Path path = new Path();

        for (int i = 0; i < data.size(); i++) {
            float x = i * deltaX;
            float y = height - (data.get(i) - minValue) * deltaYRange;

            if (i == 0) {
                path.moveTo(x, y);
            } else {
                path.lineTo(x, y);
            }
            // 绘制数据点
            canvas.drawCircle(x, y, 3f, pointPaint);
        }
        if (showIndex >= 0) {
            canvas.drawLine(showIndex, 0, showIndex, getMeasuredHeight(), clickLinePaint);
        }

        descPaint.setColor(getResources().getColor(descPaintColor));
        if (!TextUtils.isEmpty(desc)) {
            canvas.drawText(desc, 10, getMeasuredHeight() - 40, descPaint);
        }
        canvas.drawText("" + maxValue, getMeasuredWidth() - 60, 40, descPaint);
        canvas.drawText("" + minValue, getMeasuredWidth() - 60, getMeasuredHeight() - 40, descPaint);

        // 绘制折线
        canvas.drawPath(path, linePaint);
    }

    public void resetClickLine() {
        showIndex = -1;
        invalidate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    // 可配置的公共方法
    public void setLineColor(int color) {
        linePaint.setColor(color);
        invalidate();
    }

    public void setPointColor(int color) {
        pointPaint.setColor(color);
        invalidate();
    }

    public void setPointSize(float size) {
        pointPaint.setStrokeWidth(size);
        invalidate();
    }
}